import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix,accuracy_score
from sklearn.preprocessing import StandardScaler
from datetime import datetime, timedelta
plt.rcParams['font.sans-serif'] = ['SimHei']
# 生成模拟股票数据
def generate_stock_data(num_days=365, start_date="2023-01-01"):
    np.random.seed(42)
    start = datetime.strptime(start_date, "%Y-%m-%d")
    dates = [start + timedelta(days=i) for i in range(num_days)]
    # 生成基本价格序列（几何布朗运动）
    prices = [100.0]
    for _ in range(1, num_days):
        change = np.random.normal(0.001, 0.02) # 每日微小变化
        prices.append(prices[-1] * (1 + change))
        # 生成交易量
    volumes = np.random.lognormal(mean=7, sigma=0.5, size=num_days).astype(int)
        # 添加技术指标
    df = pd.DataFrame({
        'date': dates,
        'close': prices,
        'volume': volumes
    })
    # 计算技术指标
    df['5_day_ma'] = df['close'].rolling(5).mean()
    df['20_day_ma'] = df['close'].rolling(20).mean()
    df['daily_return'] = df['close'].pct_change()
    df['volatility'] = df['daily_return'].rolling(5).std()
    df['rsi'] = compute_rsi(df['close'], window=14)
    # 添加次日涨跌标签（1表示上涨，0表示下跌或持平）
    df['next_day_return'] = df['close'].pct_change().shift(-1)
    df['target'] = (df['next_day_return'] > 0).astype(int)
    return df.dropna()

        # 计算RSI指标
def compute_rsi(series, window=14):
    delta = series.diff()
    gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
    loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
    rs = gain / loss
    return 100 - (100 / (1 + rs))

    # 生成1年的股票数据
stock_df = generate_stock_data(365)
    # 1. 数据概览
print("股票数据概览:")
print(stock_df.head())
print("\n数据统计信息:")
print(stock_df.describe())
# 2. 价格走势可视化
plt.figure(figsize=(14, 7))
plt.plot(stock_df['date'], stock_df['close'], label='收盘价', linewidth=2)
plt.plot(stock_df['date'], stock_df['5_day_ma'], label='5日均线', linestyle='--')
plt.plot(stock_df['date'], stock_df['20_day_ma'], label='20日均线', linestyle='--')
plt.title('股票价格走势与技术指标')
plt.xlabel('日期')
plt.ylabel('价格')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
# 3. 交易量分析
plt.figure(figsize=(14, 5))
plt.bar(stock_df['date'], stock_df['volume'], color='skyblue', alpha=0.7)
plt.title('每日交易量')
plt.xlabel('日期')
plt.ylabel('交易量')
plt.grid(True)
plt.tight_layout()
plt.show()
# 4. RSI指标可视化
plt.figure(figsize=(14, 5))
plt.plot(stock_df['date'], stock_df['rsi'], label='RSI(14)', color='purple')
plt.axhline(70, color='red', linestyle='--', label='超买线(70)')
plt.axhline(30, color='green', linestyle='--', label='超卖线(30)')
plt.title('RSI指标')
plt.xlabel('日期')
plt.ylabel('RSI值')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
 # 5. 机器学习建模（涨跌预测）
# 特征工程
features = ['close', 'volume', '5_day_ma', '20_day_ma', 'daily_return','volatility', 'rsi']
X = stock_df[features]
y = stock_df['target']
# 标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2,
                                                        random_state=42, shuffle=False)
# 训练模型
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
# 预测
y_pred = model.predict(X_test)
# 6. 模型评估
print("\n模型评估报告:")
print(classification_report(y_test, y_pred))
print("\n混淆矩阵:")
print(confusion_matrix(y_test, y_pred))
print(f"\n准确率: {accuracy_score(y_test, y_pred):.2f}")
 # 可视化预测结果
plt.figure(figsize=(10, 6))
plt.plot(range(len(y_test)), y_test, label='实际涨跌', marker='o')
plt.plot(range(len(y_pred)), y_pred, label='预测涨跌', marker='x', linestyle='--')
plt.title('实际涨跌 vs 预测涨跌')
plt.xlabel('样本索引')
plt.ylabel('涨跌 (1=涨, 0=跌)')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
# 特征重要性
feature_importance = pd.DataFrame({
    'Feature': features,
    'Importance': model.feature_importances_
}).sort_values('Importance', ascending=False)
plt.figure(figsize=(10, 6))
sns.barplot(x='Importance', y='Feature', data=feature_importance,
                palette='viridis')
plt.title('特征重要性分析')
plt.tight_layout()
plt.show()
# 7. 回测可视化
test_dates = stock_df.iloc[-len(y_test):]['date']
plt.figure(figsize=(14, 7))
plt.plot(test_dates, stock_df.iloc[-len(y_test):]['close'], label='收盘价',
             linewidth=2)
plt.scatter(test_dates[y_test == 1], stock_df.iloc[-len(y_test):]['close'][y_test == 1],
            color='green', label='实际上涨', marker='^', s=100)
plt.scatter(test_dates[y_test == 0], stock_df.iloc[-len(y_test):]['close'][y_test
                                                                               == 0],
                color='red', label='实际下跌', marker='v', s=100)
plt.scatter(test_dates[y_pred == 1], stock_df.iloc[-len(y_test):]['close'][y_pred
                                                                               == 1],
                color='lightgreen', label='预测上涨', marker='^', s=50, alpha=0.7)
plt.scatter(test_dates[y_pred == 0], stock_df.iloc[-len(y_test):]['close'][y_pred
                                                                               == 0],
                color='pink', label='预测下跌', marker='v', s=50, alpha=0.7)
plt.title('实际与预测涨跌对比')
plt.xlabel('日期')
plt.ylabel('价格')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()